package tk.mynoteapp.dev.demo03.threadpoolreuse;

import jodd.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 务必确认清楚线程池本身是不是复用的
 *
 */
@RestController
@RequestMapping("threadpoolreuse")
public class ThreadPoolReuseController {
    private Logger logger = LoggerFactory.getLogger(ThreadPoolReuseController.class);

    @GetMapping("wrong")
    private String wrong() {
        ThreadPoolExecutor threadPool = ThreadPoolHelper.getThreadPool(); // 错误原因：getThreadPool方法每次都返回一个新的线程池
        IntStream.rangeClosed(1, 10).forEach(i -> {
            threadPool.execute(() -> {
                String payload = IntStream.rangeClosed(1, 1000000)
                        .mapToObj(__ -> "a")
                        .collect(Collectors.joining("")) + UUID.randomUUID().toString();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                }
                logger.info(payload);
            });
        });
        return "OK";
    }

    /**
     * 将初始化一个静态字段存放对线程池实例的引用并提供一个静态方法每次返回该静态字段（getRightThreadPool()）
     * @return
     */
    @GetMapping("right")
    private String right() {
        ThreadPoolExecutor threadPool = ThreadPoolHelper.getRightThreadPool();
        IntStream.rangeClosed(1, 10).forEach(i -> {
            threadPool.execute(() -> {
                String payload = IntStream.rangeClosed(1, 1000000)
                        .mapToObj(__ -> "a")
                        .collect(Collectors.joining("")) + UUID.randomUUID().toString();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                }
                logger.info(payload);
            });
        });
        return "OK";
    }

    static class ThreadPoolHelper {
        // 自定义参数线程池
        private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                10, 50, // 10个核心线程、最大线程数50
                2, TimeUnit.SECONDS, // 非核心线程超时时间：2s
                new ArrayBlockingQueue<>(1000), // 工作线程队列容量：1000
                new ThreadFactoryBuilder().setNameFormat("demo-threadpool-%d").get() // 自定义工作线程名称
        );

        // 错误获取线程池做法，将每次都返回一个新的线程池
        public static ThreadPoolExecutor getThreadPool() {
            return (ThreadPoolExecutor) Executors.newCachedThreadPool();
        }

        public static ThreadPoolExecutor getRightThreadPool() {
            return threadPool;
        }
    }

}
